<?php
/**
 * Created by PhpStorm.
 * User: boye009
 * Date: 2016/3/17
 * Time: 9:20
 */

namespace app\bbs\api;
use app\common\api\BaseApi;
use app\bbs\model\ForumPost;
use app\bbs\model\ForumThread;
use app\bbs\model\ForumAdmingroup;
use app\bbs\model\ForumForum;
use app\bbs\model\TagToFthread;
use app\system\api\MemberApi;
use app\bbs\api\BbsMemberApi;

class ForumThreadApi extends BaseApi{
    /**
     * 添加
     */
    const ADD = "bbs/ForumThreadApi/add";
    /**
     * 保存
     */
    const SAVE = "bbs/ForumThreadApi/save";
    /**
     * 保存根据ID主键
     */
    const SAVE_BY_ID = "bbs/ForumThreadApi/saveByID";
    /**
     * 删除
     */
    const DELETE = "bbs/ForumThreadApi/deletes";

    /**
     * 多选删除
     */
    const DELETE_ALL = "bbs/ForumThreadApi/delete_all";

    /**
     * 查询
     */
    const QUERY = "bbs/ForumThreadApi/query";
    const QUERY_NO_PAGE = "bbs/ForumThreadApi/queryNoPaging";
    const QUERY_PAGE    = "bbs/ForumThreadApi/queryPage";
    const QUERY_TAG     = "bbs/ForumThreadApi/queryTag";
    const MY_THREADS    = "bbs/ForumThreadApi/queryByUid";
    /**
     * 查询一条数据
     */
    const GET_INFO = "bbs/ForumThreadApi/getInfo";
    /**
     * 查询
     */
    const QUERY_WITH_COUNT = "bbs/ForumThreadApi/queryWithCount";

    /**
     * 发表主题帖子
     */
    const ADD_THREAD = "bbs/ForumThreadApi/addThread";

    /**
     * 假删除
     */
    const PRETEND_DELETE = "bbs/ForumThreadApi/pretendDeletes";

    /**
     * 假删除
     */
    const PRETEND_DELETE_BY_MAP = "bbs/ForumThreadApi/pretendDeleteByMap";

    const STICK = "bbs/ForumThreadApi/stick";

    const DIGEST = "bbs/ForumThreadApi/digest";

    /**
     * 增加
     */
    const SET_INC = "bbs/ForumThreadApi/setInc";

    /**
     * 减少
     */
    const SET_DEC ="bbs/ForumThreadApi/setDec";
    const SET_DEC2 ="bbs/ForumThreadApi/setDec2";

    /**
     * 查询首页帖子
     */
    const QUERY_HEAD_THREADS ="bbs/ForumThreadApi/queryHeadThreads";

    protected function _init(){
        $this -> model = new ForumThread();
    }

    public function delete_all($ids,$uid){
        //验证帖子
        foreach($ids as $tid){
            //获取主题帖信息
            $res2 = apiCall(ForumThreadApi::GET_INFO,array(array('tid'=>$tid)));
            if(!$res2['status']){
                return $this -> apiReturnErr($res2['info']);
            }
            if($res2['info']['status'] == -1){
                return $this -> apiReturnErr("该主题帖不存在");
            }

            //验证是否是自己的主题帖
            if($uid != $res2['info']['author_id']){
                //用户权限验证
                $res = apiCall(ForumUserAdmingroupApi::POWER,array($uid));
                if(!$res['status']){
                    return $this -> apiReturnErr($res['info']);
                }
                $power = $res['info'];
                if(is_array($power)){
                    //验证是否有删帖权限
                    if($power[ForumAdmingroup::ALLOW_DEL_POST] !=1 || ($power['fid'] != $res2['info']['fid'] && $power['fid'] != 0)){
                        return $this -> apiReturnErr("无权限");
                    }
                }else{
                    return $this -> apiReturnErr($power);
                }

            }
        }
        $map['tid'] = array('in',$ids);
        $result = apiCall(ForumThreadApi::PRETEND_DELETE_BY_MAP,array($map,$uid));
        if($result['status']){
            return $this -> apiReturnSuc($result['info']);
        }else{
            return $this -> apiReturnErr($result['info']);
        }
    }

    //TODO 权限 - fid 子版块
    public function deletes($tid,$uid){
        //获取帖子信息
        $res2 = apiCall(ForumThreadApi::GET_INFO,[['tid'=>$tid]]);
        if(!$res2['status']) return $this -> apiReturnErr('服务器故障：thread get');
        if(empty($res2['info'])) return $this->apiReturnErr('tid 错误');
        if($res2['info']['status'] == -1) return $this -> apiReturnErr("该帖已被删除");
        $fid = $res2['info']['fid'];
        //验证是否是自己的帖子
        if($uid != $res2['info']['author_id']){
            //用户权限验证
            $res = apiCall(ForumUserAdmingroupApi::POWER,array($uid));
            if(!$res['status']) return $this -> apiReturnErr($res['info']);
            $power = $res['info'];
            if( !empty($power) && is_array($power) ){
                //验证是否有删帖权限
                if($power[ForumAdmingroup::ALLOW_DEL_POST] !=1 || ($power['fid'] != $res2['info']['fid'] && $power['fid'] != 0)){
                    return $this -> apiReturnErr("无权限");
                }
            }else{
                return $this -> apiReturnErr($power);
            }
        }
        $result = apiCall(ForumThreadApi::PRETEND_DELETE,[$tid,$fid]);
        if($result['status']){
            //删除帖子标签信息
            $r = apiCall(TagToFthreadApi::QUERY_NO_PAGING,[['tid'=>$tid,'fid'=>$fid]]);
            if(!$r['status']) $this->apiReturnErr($r['info']);
            foreach ($r['info'] as $v) {
                $res = apiCall(TagToFthreadApi::DELETE,[['tid'=>$tid,'fid'=>$fid,'tag_id'=>$v['tag_id']]]);
                if(!$res['status']) $this->apiReturnErr($res['info']);
                $res = apiCall(TagApi::SET_DEC2,[['id'=>$v['tag_id']],'used',1]);
            }
            return $this -> apiReturnSuc($result['info']);
        }else{
            return $this -> apiReturnErr($result['info']);
        }
    }

    //加精
    //TODO 权限 - fid 子版块
    public function digest($uid,$tid,$digest_value){

        $map = array(
            'tid' => $tid,
        );
        $result = apiCall(ForumThreadApi::GET_INFO,array($map));
        if($result['status']){
            if(empty($result['info'])){
                return $this -> apiReturnErr('主题帖id参数错误');
            }
        }else{
            return $this -> apiReturnErr($result['info']);
        }

        //用户验证
        $res = apiCall(ForumUserAdmingroupApi::POWER,array($uid));
        if($res['status']){
            $power = $res['info'];
            if(is_array($power)){
                if($power[ForumAdmingroup::ALLOW_DIGEST_THREAD] != 1 || ($power['fid'] != $result['info']['fid'] && $power['fid'] != 0) ){
                    return $this -> apiReturnErr("无权限");
                }
            }else{
                return $this -> apiReturnErr($power);
            }
        }else{
            return $this -> apiReturnErr($res['info']);
        }

        $entity = array(
            'digest' => $digest_value,
        );
        if($digest_value == 0){
            //取消精华
            if($result['info']['digest'] == 0){
                return $this -> apiReturnErr('该帖子非精华');
            }
            $result = apiCall(ForumThreadApi::SAVE,array($map,$entity));
            if($result['status']){
                return $this -> apiReturnSuc('取消精华成功');
            }else{
                return $this -> apiReturnErr($result['info']);
            }
        }else if($digest_value == 1){
            //加精
            if($result['info']['digest'] == 1){
                return $this -> apiReturnErr('该贴子已经是精华帖');
            }
            $result = apiCall(ForumThreadApi::SAVE,array($map,$entity));
            if($result['status']){
                return $this -> apiReturnSuc('加精成功');
            }else{
                return $this -> apiReturnErr($result['info']);
            }
        }

    }

    //置顶
    //TODO 权限 - fid 子版块
    public function stick($uid,$tid,$stick_value){

        $map = array(
            'tid' => $tid,
        );
        $result = apiCall(ForumThreadApi::GET_INFO,array($map));
        if($result['status']){
            if(empty($result['info'])){
                return $this -> apiReturnErr('主题帖id参数错误');
            }
        }else{
            return $this -> apiReturnErr($result['info']);
        }

        //用户验证
        $res = apiCall(ForumUserAdmingroupApi::POWER,array($uid));
        if($res['status']){
            $power = $res['info'];
            if(is_array($power)){
                if($power[ForumAdmingroup::ALLOW_STICK_THREAD] != 1 || ($power['fid'] != $result['info']['fid'] && $power['fid'] != 0) ){
                    return $this -> apiReturnErr("无权限");
                }
            }else{
                return $this -> apiReturnErr($power);
            }
        }else{
            return $this -> apiReturnErr($res['info']);
        }

        $entity = array(
            'stick' => $stick_value,
        );
        if($stick_value == 0){
            if($result['info']['stick'] == 0){
                return $this -> apiReturnErr('该帖非置顶帖');
            }
            $result = apiCall(ForumThreadApi::SAVE,array($map,$entity));
            if($result['status']){
                return $this -> apiReturnSuc('取消置顶成功');
            }else{
                return $this -> apiReturnErr($result['info']);
            }
        }else if($stick_value == 1){
            if($result['info']['stick'] == 1){
                return $this -> apiReturnErr('该帖已经置顶');
            }
            $result = apiCall(ForumThreadApi::SAVE,array($map,$entity));
            if($result['status']){
                return $this -> apiReturnSuc('置顶成功');
            }else{
                return $this -> apiReturnErr($result['info']);
            }
        }

    }

    public function pretendDeletes($tid,$fid){
        //假删除主题帖
        $map  = ['tid' => $tid];
        $data = [
            'status' => -1,//删除状态
        ];
        $this -> model -> startTrans();//启动事务
        $forumModel = new ForumForum();
        $result = $this -> model -> where($map) -> save($data);
        if($result === false){
            $error = $this -> model -> getDbError();
            return $this -> apiReturnErr($error);
        }else{

            $map = [
                'fid' => $fid,
            ];
            $result = $forumModel -> where($map) -> setDec('threads');
            if($result === false){
                $error = $forumModel -> getError();
                $this -> model -> rollback();
                return $this -> apiReturnErr($error);
            }else{
                $this -> model -> commit();
                return $this -> apiReturnSuc("删除成功!");
            }
        }

    }

    public function pretendDeleteByMap($map,$fid){
        //假删除主题帖
        $data = array(
            'status' => -1,//删除状态
        );
        $this -> model -> startTrans();//启动事务
        $forumModel = new ForumForum();
        $result = $this -> model -> where($map) -> save($data);
        if($result === false){
            $error = $this -> model -> getDbError();
            return $this -> apiReturnErr($error);
        }else{
            $num = count($map['tid']['in']);
            $map = array(
                'fid' => $fid,
            );
            $result = $forumModel -> where($map) -> setDec('threads',$num);
            if($result === false){
                $error = $forumModel -> getError();
                $this -> model -> rollback();
                return $this -> apiReturnErr($error);
            }else{
                $this -> model -> commit();
                return $this -> apiReturnSuc("删除成功!");
            }
        }

    }


    public function queryWithCount($map = null, $map_invisible = null, $page = array('curpage'=>0,'size'=>10), $order = false, $params = false, $fields = false){

        $query = $this->model -> join("(select tid,invisible from itboye_forum_post where position=0) as post on itboye_forum_thread.tid=post.tid") -> join("itboye_forum_forum on itboye_forum_thread.fid=itboye_forum_forum.fid","left");
        if(!is_null($map)){
            $query = $query->where($map);
        }
        if(!is_null($map_invisible)){
            $query = $query -> where($map_invisible);
        }
        if(!($order === false)){
            $query = $query->order($order);
        }
        if(!($fields === false)){
            $query = $query->field($fields);
        }
        $list = $query -> page($page['curpage'] . ',' . $page['size']) -> select();

        if ($list === false) {
            $error = $this -> model -> getDbError();
            return $this -> apiReturnErr($error);
        }

        if(!is_null($map_invisible)){
            $count = $this -> model -> where($map) -> where($map_invisible) -> join("(select tid,invisible from itboye_forum_post where position=0) as post on itboye_forum_thread.tid=post.tid") -> join("itboye_forum_forum on itboye_forum_thread.fid=itboye_forum_forum.fid","left") -> count();
        }else{
            $count = $this -> model -> where($map) -> join("(select tid,invisible from itboye_forum_post where position=0) as post on itboye_forum_thread.tid=post.tid") -> join("itboye_forum_forum on itboye_forum_thread.fid=itboye_forum_forum.fid","left") -> count();
        }

        // 查询满足要求的总记录数
        // $Page = new Page($count, $page['size']);

        // //分页跳转的时候保证查询条件
        // if ($params !== false) {
        //     foreach ($params as $key => $val) {
        //         $Page -> parameter[$key] = urlencode($val);
        //     }
        // }

        // // 实例化分页类 传入总记录数和每页显示的记录数
        // $show = $Page -> show();
        // return $this -> apiReturnSuc(array("count" => $count, 'show' => $show, "list" => $list));
        return $this -> apiReturnSuc(array("count" => $count, "list" => $list));

    }

    public function addThread($thread_entity,$post_entity){

        $tid = 0;
        $this -> model -> startTrans();//开启事务
        $result = $this -> model -> create($thread_entity,1);

        $error = false;
        if($result === false){
            $error = $this -> model -> getDbError();
        }else{
            $result = $this -> model -> add();
            if($result === false){
                $error = $this -> model -> getDbError();
            }else{
                $tid = $result;
            }
        }

        if($error === false){
            //未出错
            $forumPost = new ForumPost();
            $post_entity['tid'] = $tid;
            $result = $forumPost -> create($post_entity,1);

            if($result === false){
                $error = $this -> model -> getDbError();
                $this -> model -> rollback();
            }else{
                $result = $forumPost -> add();
                if($result === false){
                    $error = $this -> model -> getDbError();
                    $this -> model -> rollback();
                }else{
                    $pid = $result;
                    $this -> model -> commit();
                    $allId = array(
                        'tid' => $tid,
                        'pid' => $pid,
                    );
                    return $this -> apiReturnSuc($allId);
                }
            }
        }

        return $this -> apiReturnErr($error);

    }
    /**
     * 我的帖子查询 分页
     */
    public function queryByUid($map,$page=1,$size=10,$order='tid desc'){
        $where = [];
        $where['_string'] = '`status`>=0';
        if(isset($map['num'])){
            $num = intval($map['num']);
        }else{
            $num = 3;
        }
        // if(isset($map['fid']) && intval($map['fid'])>0) $where['fid']= intval($map['fid']);
        if(isset($map['_string'])) $where['_string'] = $where['_string'].' and '.$map['_string'];
        if(isset($map['uid'])) $where['author_id']= intval($map['uid']);

        // $where = '`author_id`=\''.$uid.'\' and `status`>=0 ';
        // if($fid>0) $where = ' and `fid`='.$fid;
        $page  = intval($page)>1 ?intval($page):1;
        $start = ($page-1)*$size;
        $count = $this -> model ->field('tid')->where($where)->count();
        $list  = $this -> model ->where($where)->limit($start,$size)->order($order)->select();
        // ->buildSql();
        // return $this->apiReturnErr($list);
        if(0==$count || !$list) return $this->apiReturnSuc(['count'=>0,'list'=>[]]);
        // trace('---list---');
        // trace($list);
        foreach ($list as &$val) {
            //获取发表时间展示信息
            $time = time() - $val['dateline'];
            $val['dateline_show'] = $this->getDateInfo($time,$val['dateline']);
            //查询用户信息
            $userInfo = $this->getUserInfo($val['author_id']);
            if(!$userInfo['status']) return $this->apiReturnErr($userInfo['info']);
            $userInfo = $userInfo['info'];
            $val['head']   = $userInfo['head'];
            $val['author'] = $userInfo['nickname'];
            $val['sex']    = $userInfo['sex'];
            $val['group']  = $userInfo['group'];
            //获取图片信息
            $map = [
                'tid' => $val['tid'],
            ];
            $field = "aid,pid";
            $res = apiCall(ForumAttachmentApi::QUERY_NO_PAGING,array($map,false,$field));
            if($res['status']){
                $val['img'] = [];
                $i = 0;
                foreach($res['info'] as $v){
                    array_push($val['img'],$v['aid']);
                    $i++;
                    if($i == $num) break;
                }
            }else{
                return $this -> apiReturnErr($res['info']);
            }
        }
        return $this->apiReturnSuc(['count'=>$count,'list'=>$list]);
    }
    /**
     * 帖子分页 - tag+fid
     */
    public function queryTag($map=null,$page=1,$size=10,$order='tid desc'){
        $where = ' `t`.`status`<>-1 '; //-1 删除 0 正常 1审核
        if($map){
            if(isset($map['fid'])){
                $fid = intval($map['fid']);
                if($fid){
                    $r = apiCall(ForumForumApi::GET_FID_WITH_CHILD,[$fid]);
                    if(!$r['status']) return $this->apiReturnErr($r['info']);
                    if($r['info']) $where .= ' and `t`.`fid` in ('.implode(',', $r['info']).') ';
                }
            }
            if(isset($map['tag_id'])){
                $where .=' and `tag`.`tag_id` = '.intval($map['tag_id']);
            }
        }
        if($map && isset($map['imgs'])){
            $num = intval($map['imgs']);
        }else{
            $num = 3;
        }
        $count = $this-> model->alias('t')
        ->join('right join itboye_tag_to_fthread as tag on tag.tid=t.tid')->where($where)->field('t.tid')->count();
        $start = ($page-1)*$size;
        $list  = $this-> model->alias('t')->join('right join itboye_tag_to_fthread as tag on tag.tid=t.tid')->where($where) ->limit($start,$size) ->order('t.'.$order)->select();
        if(false === $list) return $this->apiReturnErr($this-> model->getDbError());
        foreach ($list as &$val) {
            //获取发表时间展示信息
            $time = time() - $val['dateline'];
            $val['dateline_show'] = $this->getDateInfo($time,$val['dateline']);
            //查询用户信息
            $userInfo = $this->getUserInfo($val['author_id']);
            if(!$userInfo['status']) return $this->apiReturnErr($userInfo['info']);
            $userInfo = $userInfo['info'];
            $val['head']   = $userInfo['head'];
            $val['sex']    = $userInfo['sex'];
            $val['author'] = $userInfo['nickname'];
            $val['group']  = $userInfo['group'];
            //获取图片信息
            $map = [
                'tid' => $val['tid'],
            ];
            $field = "aid,pid";
            $res = apiCall(ForumAttachmentApi::QUERY_NO_PAGING,array($map,false,$field));
            if($res['status']){
                $val['img'] = [];
                $i = 0;
                foreach($res['info'] as $v){
                    array_push($val['img'],$v['aid']);
                    $i++;
                    if($i == $num) break;
                }
            }else{
                return $this -> apiReturnErr($res['info']);
            }
        }
        return $this->apiReturnSuc(['count'=>$count,'list'=>$list]);
    }
    /**
     * 帖子分页 - 置顶优先
     * @param $page
     * @param $size
     * @return array
     */
    public function queryPage($map=null,$page=1,$size=10,$order='tid desc'){
        $where = ' `status`<>-1 '; //-1 删除 0 正常 1审核
        if($map){
            if(isset($map['fid'])){
                $fid = intval($map['fid']);
                if($fid){
                    $cacheKey = 'forum_block_'.$fid;
                    $ids = S($cacheKey);
                    if($ids){
                       $where .= ' and `fid` in ('.$ids.') ';
                    }else{
                        $r = apiCall(ForumForumApi::GET_FID_WITH_CHILD,[$fid]);
                        if(!$r['status']) return $this->apiReturnErr($r['info']);
                        if($r['info']){
                            $ids = implode(',', $r['info']);
                            S($cacheKey,$ids,600);
                            $where .= ' and `fid` in ('.$ids.') ';
                        }
                    }
                }
            }
            // if(isset($map['title'])){
            // $where .=' and `subject` like \'%'.$map['title'].'%\' ';
            // }
            // if(isset($map['digest'])){
            //     $where .=' and `digest`= '.$map['digest'].' ';
            // }
        }
        $num = isset($map['imgs'])?intval($map['imgs']):3;//
        unset($map);
        $start = max(intval($page-1)*$size,0);
        // $start = ($start>0)? $start:0;
        // $end   = $start + $size;
        //分开查询 - 优先查询置顶帖子
        $field = 'dateline,author_id,replies,likes,subject,fid,tid,views,message';
        $model = $this->model;
        $count = $model->field('tid')->where($where.' and `stick`=1 ')->count();
        $count1 = $model->field('tid')->where($where.' and `stick`=0 ')->count();
        $p     = floor($count/$size); //页码 $p页置顶 + $plast
        $plast = ceil($count%$size); //页码
        if($page<=$p){
            $result = $model->where($where.' and stick=1')->limit($start,$size)->order($order)->select();
        }elseif($plast && $page == ($p+1)){
            $result1 = $model->where($where.' and stick=1')->limit($start,$plast)->order($order)->select();
            $result2 = $model->where($where.' and stick=0')->limit(0,($size-$plast))->order($order)->select();
            $result = array_merge($result1,$result2);
            unset($result1);unset($result2);
        }else{
            $start = intval($page-$p-1)*$size - $plast;
            $result = $model->where($where.' and stick=0')->limit($start,$size)->order($order)->select();
        }
        //一次查询 - 优先查询置顶帖子
        // $model  = new \think\Model();
        // $sql    = 'select * from (select '.$field.' from itboye_forum_thread where '.$where.' and stick=1 order by '.$order.') temp1 union select * from (select '.$field.' from itboye_forum_thread where '.$where.' and stick=0 order by '.$order.') temp2 limit '.$start.','.$size;
        // $count  = $this->model ->where($where)->count();
        // if(false === $count) $this->apiReturnErr($this->model->getDbError());
        // $result = $model ->query($sql);
        if(false === $result){
            return $this->apiReturnErr($model->getDbError());
        }else{
            $threads = $result;
            //查询附件、作者信息
            foreach($threads as &$val){
                //获取发表时间展示信息
                $time = time() - $val['dateline'];
                $val['dateline_show'] = $this->getDateInfo($time,$val['dateline']);
                //查询用户信息
                $userInfo = $this->getUserInfo($val['author_id']);
                if(!$userInfo['status']) return $this->apiReturnErr($userInfo['info']);
                $userInfo = $userInfo['info'];
                $val['head']   = $userInfo['head'];
                $val['author'] = $userInfo['nickname'];
                $val['sex']    = $userInfo['sex'];
                $val['group']  = $userInfo['group'];
                //获取图片信息
                $map = [
                    'tid' => $val['tid'],
                ];
                $field = "aid,pid";
                $res = apiCall(ForumAttachmentApi::QUERY,array($map,['curpage'=>1,'size'=>$num],false,false,$field));
                if($res['status']){
                    $val['img'] = [];
                    foreach($res['info']['list'] as $v){
                        array_push($val['img'],$v['aid']);
                    }
                }else{
                    $this -> apiReturnErr($res['info']);
                }
            }
            // return $this->apiReturnSuc(['count'=>$count,'list'=>$threads]);
            return $this->apiReturnSuc(['count'=>($count+$count1),'list'=>$threads]);
        }
    }

/******************** private ****************************************/
    private  function getDateInfo($time,$dateline){

        if($time <= 60){
            return "刚刚";
        }else if($time > 60 && $time <= 3600){
            return floor($time/60)."分钟前";
        }else if($time > 3600 && $time <= 3600*24){
            return floor($time/3600)."小时前";
        }else if($time > 3600*24){
            return date('Y-m-d',$dateline);
        }

    }

    /**
     * 查询用户信息
     */
    private function getUserInfo($uid){
        // $r = apiCall(MemberApi::GET_INFO,array($uid));
        $r = apiCall(BbsMemberApi::GET_USER_INFO,[$uid,true,false,false,false]);
        if($r['status'] && $r['info']){
            return $this->apiReturnSuc($r['info']);
        }else{
            return $this->apiReturnErr('查询用户信息失败'.$uid);
        }
    }

}